package com.chinasoft;

import javax.swing.*;
import javax.swing.plaf.FontUIResource;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * GamePanel 类继承自 JPanel，用于游戏界面的绘制和逻辑控制
 */
@EqualsAndHashCode(callSuper = true)
@Data
public class GamePanel extends JPanel implements KeyListener {
    private static final long serialVersionUID = 4580018968485363291L;
    // 定义一个数组用于存储游戏背景图片
    private Image[] bases = new Image[10];
    // 定义一个布尔变量用于控制主角的移动方向
    private MapData data;

    /**
     * GamePanel 构造函数，用于初始化游戏面板的属性
     */
    public GamePanel() {
        // 设置游戏面板的背景色
        this.setBackground(Color.GRAY);
        // 设置游戏面板的边界，即面板的大小
        this.setBounds(0, 0, 1000, 1000);
        // 初始化游戏背景图片
        initBases();
        // 添加键盘监听器，用于监听键盘事件，实现主角移动
        this.setFocusable(true);
        this.addKeyListener(this);
        this.setVisible(true);
        this.requestFocus();
        data = new MapData();
        repaint();
        // 加载地图
//        MapData mapData = new MapData();
//        mapData.loadMap(1);
    }

    /**
     * initBases 方法用于初始化游戏背景图片
     */
    public void initBases() {
        // 遍历数组，加载并存储背景图片
        for (int i = 0; i < 10; i++) {
            bases[i] = Toolkit.getDefaultToolkit().getImage(GamePanel.class.getResource("/image/scene/" + i + ".gif"));
        }
    }

    public void initLevel(int L) {
        boolean ret = data.initLevel(L);
        repaint(); // 刷新界面
    }


    /**
     * 进入下一个级别
     * 此方法用于将当前级别推进到下一个级别，并重新绘制界面
     *
     * @return boolean 表示是否成功进入下一个级别
     */
    public boolean nextLevel() {
        // 调用data对象的nextLevel方法，获取是否成功进入下一个级别的结果
        boolean ret = data.nextLevel();
        // 重新绘制界面，以反映级别变化
        repaint();
        // 返回是否成功进入下一个级别的结果
        return ret;
    }


    /**
     * 重写paint方法以自定义组件的绘制行为
     *
     * @param g Graphics对象，用于绘制图形和图像
     */
    public void paint(Graphics g) {
        int[][] map = data.getMap();
        // 遍历二维数组，绘制基础图形或图像
        for (int y = 0; y < data.WIDTH; y++) {
            for (int x = 0; x < data.WIDTH; x++) {
                // 在每个坐标点上绘制图像，图像来自bases数组的第一个元素
                // 每隔50个px绘制一个背景草坪图像，因为图像的大小是50*50
                int id = map[y][x];
                switch (id) {
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                        g.drawImage(bases[0], x * 50, y * 50, this);
                    default:
                        g.drawImage(bases[id], x * 50, y * 50, this);
                        break;

                }
                // observer:this 是什么意思？
            }
        }

        // g.drawLine(10, 10, 200, 200);
    }


    @Override
    public void keyTyped(KeyEvent e) {
        // null
    }

    /**
     * 当键盘按键被按下时调用此方法
     *
     * @param e 键盘事件对象，包含按键信息
     */
    @Override
    public void keyPressed(KeyEvent e) {
        // 获取游戏中的玩家对象
        Man man = data.getMan();
        // 打印按键的代码，用于调试
        System.out.println(e.getKeyCode());
        // 根据按键代码执行相应的操作
        switch (e.getKeyCode()) {
            case KeyEvent.VK_UP:
                // 当按下向上键时，玩家向上移动
                man.move(Direction.Up);
                // 重新绘制界面
                repaint();
                break;
            case KeyEvent.VK_DOWN:
                // 当按下向下键时，玩家向下移动
                man.move(Direction.Down);
                // 重新绘制界面
                repaint();
                break;
            case KeyEvent.VK_LEFT:
                // 当按下向左键时，玩家向左移动
                man.move(Direction.Left);
                // 重新绘制界面
                repaint();
                break;
            case KeyEvent.VK_RIGHT:
                // 当按下向右键时，玩家向右移动
                man.move(Direction.Right);
                // 重新绘制界面
                repaint();
                break;
            default:
                // 其他按键不执行任何操作
                break;
        }
        // 检查是否胜利
        if (data.isWin() == true) {
            // 如果已经是最后一关
            if (data.getLevel() == MapData.MAX_LEVEL) {
                // 显示提示信息
                JOptionPane.showMessageDialog(this, " 已经是最后一关了 ！");
            } else {
                // 提示玩家是否进入下一关
                String msg = "是否要进入下一关？";
                // 设置提示对话框的字体样式
                UIManager.put("OptionPane.messageFont", new FontUIResource(new Font("宋体", Font.ITALIC, 15)));
                // 显示确认对话框
                int confirm = JOptionPane.showConfirmDialog(this, msg, "过关", JOptionPane.YES_NO_OPTION);
                // 如果玩家选择是
                if (confirm == JOptionPane.YES_OPTION) {
                    // 进入下一关
                    nextLevel();
                } else {
                    // 如果玩家选择否，不执行任何操作
                    return;
                }
            }
        }
    }


    @Override
    public void keyReleased(KeyEvent e) {
        // null
    }


    public void requestFocusWindow() {
        this.requestFocus();
    }
}
